<template>
  <div class="comp-g-scan">
    <van-field v-model="fieldValue" :type="type" :readonly="readonly" :name="name" :label="label" :placeholder="placeholder" :required="required" :rules="rules" @close="handleClose">
      <template #button>
        <van-icon name="scan" size="25" @click.stop="openScan" />
      </template>
    </van-field>
  </div>
  <van-action-sheet class="scan-action" v-if="showScanDialog" v-model:show="showScanDialog" :round="false" :title="label + '扫码'">
    <div class="scan-content">
      <div class="content">
        <video ref="videoRef" class="video"></video>
        <div class="deviceds" v-if="deviceds.length">
          <div class="device-title">请选择摄像头</div>
          <van-cell v-if="selectedDeviceId" :title="selectedDeviceName" is-link @click="changeDevice" />
        </div>

        <van-cell v-if="scanResult" title="扫码结果：" :value="scanResult" />
      </div>

      <div class="scan-footer">
        <van-button block round type="primary" @click="handleStart">开始</van-button>
        <van-button block round type="primary" @click="handleRest">重置</van-button>
        <van-button block round type="primary" @click="handleOk">确定</van-button>
      </div>
    </div>
  </van-action-sheet>
  <van-action-sheet v-model:show="showPicker" :actions="deviceds" @select="onSelect" cancel-text="取消" description="切换摄像头" close-on-click-action />
</template>

<script setup>
import { onMounted, ref, watch } from 'vue'
import { BrowserMultiFormatReader } from '@zxing/library'

const props = defineProps({
  label: String,
  name: String,
  placeholder: String,
  modelValue: [String, Number],
  readonly: {
    type: Boolean,
    default: false
  },
  type: {
    type: String,
    default: 'text'
  },
  rules: Array,
  required: {
    type: Boolean,
    default: true
  }
})
const emits = defineEmits(['update:modelValue'])

const fieldValue = ref(props.modelValue)
watch(
  () => props.modelValue,
  (newVal) => {
    fieldValue.value = newVal
  }
)

const showScanDialog = ref(false)
const openScan = () => {
  showScanDialog.value = true
  if (codeReader.value) {
    codeReader.value.reset()
  }
  initScan()
}
const handleClose = () => {
  showScanDialog.value = false
  emits('update:modelValue', false)
}

const scanResult = ref('')
const videoRef = ref(null)
const codeReader = ref(null)
const selectedDeviceId = ref(null)
const selectedDeviceName = ref('')
const deviceds = ref([])
const showPicker = ref(false)
const initScan = () => {
  codeReader.value = new BrowserMultiFormatReader()
  console.log('codeReader.value', codeReader.value)

  codeReader.value
    .listVideoInputDevices()
    .then((res) => {
      console.log(res)
      const currentDevice = res.filter((item) => item.label.includes('back'))
      console.log('currentDevice', currentDevice)
      if (currentDevice.length) {
        selectedDeviceId.value = currentDevice[0].deviceId
        selectedDeviceName.value = currentDevice[0].label
      } else {
        selectedDeviceId.value = res[0].deviceId
        selectedDeviceName.value = res[0].label
      }

      console.log('currentDevice-->1', selectedDeviceId.value)
      console.log('currentDevice-->2', selectedDeviceName.value)
      if (res.length >= 1) {
        res.forEach((element) => {
          deviceds.value.push({
            name: element.label,
            value: element.deviceId
          })
        })
      }
      handleStart()
    })
    .catch((err) => {
      console.log('err', err)
    })
}

const handleStart = () => {
  codeReader.value.decodeFromVideoDevice(selectedDeviceId.value, videoRef.value, (result, err) => {
    if (result) {
      scanResult.value = result.text
      console.log('codeReader.value ', result)
    }
  })
}
const handleRest = () => {
  codeReader.value.reset()
  scanResult.value = ''
}
const handleOk = () => {
  fieldValue.value = scanResult.value
  showScanDialog.value = false

  codeReader.value.reset()
}

const changeDevice = () => {
  showPicker.value = true
}

const onSelect = (val) => {
  selectedDeviceId.value = val.value
  selectedDeviceName.value = val.name
  showPicker.value = false
}

onMounted(() => {
  console.log('')
  // initScan()
})
</script>

<style lang="less">
.scan-action {
  height: 100vh;
  max-height: 90vh;
}
.scan-content {
  position: relative;
  height: 100%;
  .content {
    flex: 1;
    .video {
      width: 100%;
      height: 50vh;
      border: 1px solid #ccc;
      box-sizing: border-box;
    }
    .deviceds {
      margin-top: 10px;
      display: flex;
      flex-direction: column;
      .device-title {
        padding: 3px 15px;
        font-weight: bold;
      }
    }
  }
  .scan-footer {
    position: absolute;
    left: 50%;
    bottom: 10px;
    z-index: 10;
    display: flex;
    width: 90%;
    margin-left: -45%;
    .van-button {
      flex: 1;
      margin: 0 3px;
    }
  }
}
</style>
